/*
 * Lenovo Group
 * Copyright (c) 2015-2016 All Rights Reserved.
 * 
 * Project Name:itsm-gateway
 * Create Time: 2016年2月5日 上午10:28:09
 */
package com.lenovo.lmrp.server.itsmgateway.domain.ticket;

import java.io.InputStream;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lenovo.lmrp.api.model.entity.AttachmentPO;
import com.lenovo.lmrp.api.model.entity.AttachmentPO.AttachmentStatus;
import com.lenovo.lmrp.base.IFileService;
import com.lenovo.lmrp.server.itsmgateway.adapter.AItsmAdapter;
import com.lenovo.sdc.framework.util.Tuple;
import com.lenovo.sdc.framework.util.exception.ErrorCode;
import com.lenovo.sdc.framework.util.exception.TraceableException;

/**
 * 
 * @author wujin
 * @version v1.0
 */
public class AttachmentBO {
    private static final Logger logger = LoggerFactory.getLogger(AttachmentBO.class);
    
    private String itsmCode;
    private AttachmentPO attachmentPO;
    private boolean isdirty;

    private AItsmAdapter adapter;
    
    public AttachmentBO(AItsmAdapter adapter, String itsmCode, AttachmentPO attachmentPO) {
        this.itsmCode = itsmCode;
        this.attachmentPO = attachmentPO;
        this.adapter = adapter;
        
        this.isdirty = false;
    }
    
    public String getID() {
        return attachmentPO.getId();
    }

    public void changeStatus(String submitter, AttachmentStatus status) {
        if (attachmentPO.getStatus().equals(AttachmentStatus.SYNCED))
            return;
        
        attachmentPO.setSubmitter(submitter);
        attachmentPO.setStatus(status);
        isdirty = true;
    }
    
    public void setPath(String storePath, String cdnURL) {
        if (Objects.nonNull(cdnURL)) {
            attachmentPO.setCdnURL(cdnURL);
            isdirty = true;
        }
        
        if (Objects.nonNull(storePath)) {
            attachmentPO.setStorePath(storePath);
            isdirty = true;
        }
    }
    
    public void attachTicket(String ticketID) {
        if (Objects.isNull(attachmentPO.getTicketId()))
            attachmentPO.setTicketId(ticketID);
        else if (attachmentPO.getTicketId().equals(ticketID))
            return;
        else
            attachmentPO.setTicketId(ticketID);
        isdirty = true;
    }
    
    /**
     * upload UNSYNCED file to ITSM, it status isn't UNSYNCED, or file not exist will throw TraceableException
     */
    public void syncAttachment() {
        switch(attachmentPO.getStatus()) {
            case UNUPLOADED:
            case UPLOADING:
                throw new TraceableException(ErrorCode.COMM_PARAM_INVALID, "please unload file first");
            case SYNCING:
                throw new TraceableException(ErrorCode.COMM_PARAM_INVALID, "file is uploading to ITSM");
            case SYNCED: {
                logger.info("upload ticket {} attachment {} to ITSM again", 
                    attachmentPO.getTicketId(), attachmentPO.getFileName());
            }
            case UPLOADED: {
                // get ITSM Adapter to sync file
                Tuple.Pair<Boolean, String> result = adapter.uploadTicketAttachment(attachmentPO);
                if (result.getOne() == false)
                    throw new TraceableException(ErrorCode.COMM_ERROR, result.getSecond());
                else {
                    attachmentPO.setStatus(AttachmentStatus.SYNCED);
                    isdirty = true;
                }
            }
        }
    }
    
    public void saveContent(String fileName, IFileService fileHelper, InputStream in) {
        attachmentPO.setStatus(AttachmentStatus.UPLOADING);
        try {
            Tuple.Pair<String, Long> result = fileHelper.writeFile(itsmCode + "/" 
                                                    + attachmentPO.getTicketId() + "/" 
                                                    + attachmentPO.getId() + "-" + fileName, in);
            attachmentPO.setFileName(fileName);
            attachmentPO.setStorePath(result.getOne());
            attachmentPO.setStatus(AttachmentStatus.UPLOADED);
            isdirty = true;
        }
        catch (TraceableException exp) {
            attachmentPO.setStatus(AttachmentStatus.UNUPLOADED);
            throw exp;
        }
    }
    
    public void store(ITicketRepository repository) {
        if (isdirty)
            repository.storeTicketAttachment(itsmCode, attachmentPO);
        
        isdirty = false;
    }
}
